#include "stdafx.h"
#include "FlexGraphInterface.h"


FG_EXPORT _FGHandle FG_createGraphControl(void* hWnd,
                                          _s32 Left,
                                          _s32 Top,
                                          _s32 Width,
                                          _s32 Height,
                                          _s32 WindowLeft,
                                          _s32 WindowTop)
{
    CRect Rect(Left + WindowLeft,
               Top + WindowTop,
               Left + WindowLeft + Width,
               Top + WindowTop + Height
              );
    CWnd* pParentWnd = CWnd::FromHandle(HWND(hWnd));

    // Check if the parent window is valid
    if(pParentWnd == NULL)
    {
        return FG_ERROR_NULLPOINTER_PARAMETER;
    }

    // Ensure we are using our own resources and create graph control
    // When the dialog is created, move it into the specified rectangle
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    shared_ptr<_GraphDialog> pDialog(new _GraphDialog(pParentWnd, Rect, CreatedGraphs));
    pDialog->Create(IDD_FLEX_GRAPH_INTERNAL_GRAPH_DIALOG, pParentWnd);
    OpenGraphs[CreatedGraphs++] = pDialog;
    pDialog->SetWindowPos(pParentWnd, 0, 0,
                          Width + Left,
                          Height + Top,
                          SWP_NOZORDER | SWP_NOACTIVATE
                         );
    pDialog->ShowWindow(SW_SHOW);
    return CreatedGraphs - 1;
}

FG_EXPORT _s32 FG_removeGraphControl(_FGHandle ControlHandle)
{
    auto Iterator = OpenGraphs.begin();

    for(; Iterator != OpenGraphs.end() && OpenGraphs.size() != 0;)
    {
        if(Iterator->first == ControlHandle)
        {
            // Found the correct control, remove it
            Iterator = OpenGraphs.erase(Iterator);
            return EXIT_SUCCESS;
        }
        else
        {
            Iterator++;
        }
    }

    return EXIT_FAILURE;
}

FG_EXPORT void FG_setFullscreen(_FGHandle ControlHandle, bool Enable)
{
    // todo!
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return ;
    }
    else
    {
        shared_ptr<_GraphDialog> pDlg = OpenGraphs.at(ControlHandle);

        if(Enable = true)
        {
            pDlg->SetParent(CWnd::FromHandle(GetDesktopWindow()));
            // Calculates span of display area
            HDC hDC = ::GetDC(NULL);
            int XSpan = GetDeviceCaps(hDC, HORZRES);
            int YSpan = GetDeviceCaps(hDC, VERTRES);
            ::ReleaseDC(NULL, hDC);
            CRect Rect = CRect(0, 0, XSpan / 2, int(YSpan / 1.5));
            pDlg->getGraphControl()->SetParent((CWnd::FromHandle(HWND_TOPMOST)));
            pDlg->getGraphControl()->SetWindowPos(CWnd::FromHandle(HWND_TOPMOST), 00, 0, Rect.Width(), Rect.Height(), 0);
            pDlg->getGraphControl()->setRect(Rect);
            pDlg->SetWindowPos(CWnd::FromHandle(HWND_TOPMOST), 0, 0, Rect.Width(), Rect.Height(), 0);
        }
        else
        {
        }
    }
}

FG_EXPORT _FGHandle FG_addGraphEx(_FGHandle ControlHandle)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }
    else
    {
        return (OpenGraphs.at(ControlHandle)->getGraphControl()->addGraph(L""));
    }
}

FG_EXPORT _FGHandle FG_addGraph(_FGHandle ControlHandle, WCHAR* Title)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }
    else if(Title == NULL)
    {
        return FG_ERROR_NULLPOINTER_PARAMETER;
    }
    else
    {
        return (OpenGraphs.at(ControlHandle)->getGraphControl()->addGraph(Title));
    }
}

FG_EXPORT _s32 FG_setVisible(_FGHandle ControlHandle, bool Visible)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->ShowWindow(Visible);
    return EXIT_SUCCESS;
}

FG_EXPORT _s32 FG_getVisible(_FGHandle ControlHandle, bool* pVisible)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    if(pVisible == NULL)
    {
        return FG_ERROR_NULLPOINTER_PARAMETER;
    }

    *pVisible = (OpenGraphs.at(ControlHandle)->getGraphControl()->IsWindowVisible() == TRUE);
    return EXIT_SUCCESS;
}

FG_EXPORT _2DPoint* FG_getPoints(_FGHandle ControlHandle, _FGHandle GraphHandle)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return NULL;
    }

    auto Graphs = OpenGraphs.at(ControlHandle)->getGraphControl()->getGraphs();

    if(Graphs->count(GraphHandle) == 0)
    {
        return NULL;
    }

    return &(Graphs->at(GraphHandle).getPoints()->at(0));
}

FG_EXPORT _u32 FG_getNumberOfPoints(_FGHandle ControlHandle, _FGHandle GraphHandle)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return NULL;
    }

    auto Graphs = OpenGraphs.at(ControlHandle)->getGraphControl()->getGraphs();

    if(Graphs->count(GraphHandle) == 0)
    {
        return NULL;
    }

    return Graphs->at(GraphHandle).getPoints()->size();
}

FG_EXPORT _s32 FG_addPoint(_FGHandle ControlHandle, _FGHandle GraphHandle, double x, double y)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    if(OpenGraphs.at(ControlHandle)->getGraphControl()->getGraphs()->count(GraphHandle) == 0)
    {
        return FG_ERROR_INVALID_GRAPH_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->addPoint(GraphHandle, x, y, false);
    return EXIT_SUCCESS;
}

FG_EXPORT _s32 FG_requestRedraw(_FGHandle ControlHandle)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->RedrawWindow();
    return EXIT_SUCCESS;
}

FG_EXPORT _s32 FG_setMinMax(_FGHandle ControlHandle,
                            double X_Min,
                            double X_Max,
                            double Y_Min,
                            double Y_Max)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setMinMax(X_Min, X_Max, Y_Min, Y_Max);
    return EXIT_SUCCESS;
}

FG_EXPORT _s32 FG_getMinMax(_FGHandle ControlHandle,
                            double* X_Min,
                            double* X_Max,
                            double* Y_Min,
                            double* Y_Max)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    if(X_Min == NULL || X_Max == NULL || Y_Min == NULL || Y_Max == NULL)
    {
        return FG_ERROR_NULLPOINTER_PARAMETER;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->getMinMax(X_Min, X_Max, Y_Min, Y_Max);
    return EXIT_SUCCESS;
}

FG_EXPORT _s32 FG_setDefaultZoom(_FGHandle ControlHandle)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setDefaultZoom();
    return EXIT_SUCCESS;
}

FG_EXPORT _s32 FG_getNumOfGraphs(_FGHandle ControlHandle)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    map<int, _GraphData>* pGraphContainer = OpenGraphs.at(ControlHandle)->getGraphControl()->getGraphs();
    return pGraphContainer->size();
}

FG_EXPORT _s32 FG_setLineColor(_FGHandle ControlHandle,
                               _FGHandle GraphHandle,
                               COLORREF Color)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setLineColor(GraphHandle, Color);
    return EXIT_SUCCESS;
}

FG_EXPORT _s32 FG_getBorderSize(_FGHandle ControlHandle, _u32* pSize)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    if(pSize == NULL)
    {
        return FG_ERROR_NULLPOINTER_PARAMETER;
    }

    *pSize = OpenGraphs.at(ControlHandle)->getGraphControl()->getBorderSize();
    return EXIT_SUCCESS;
}

FG_EXPORT _s32      FG_setBorderSize(_FGHandle ControlHandle, _u32 Size)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    _s32 Return = EXIT_SUCCESS;
    _u32 TempSize = Size;

    if(TempSize > 9)
    {
        TempSize = 9;
        Return = FG_ERROR_BORDER_SIZE_CAPPED;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setBorderSize(TempSize);
    return Return;
}

FG_EXPORT _s32  FG_getBorderColor(_FGHandle ControlHandle, _u32* pColor)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    if(pColor == NULL)
    {
        return FG_ERROR_NULLPOINTER_PARAMETER;
    }

    *pColor = OpenGraphs.at(ControlHandle)->getGraphControl()->getBorderColor();
    return EXIT_SUCCESS;
}

FG_EXPORT _s32 FG_setBorderColor(_FGHandle ControlHandle, COLORREF Color)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setBorderColor(Color);
    return EXIT_SUCCESS;
}

FG_EXPORT _s32 FG_getLineColor(_FGHandle ControlHandle, _FGHandle GraphHandle, _u32* pColor)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    if(pColor == NULL)
    {
        return FG_ERROR_NULLPOINTER_PARAMETER;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->getLineColor(GraphHandle, pColor);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_setPointColor(_FGHandle ControlHandle, _FGHandle GraphHandle, COLORREF Color)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setPointColor(GraphHandle, Color);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_getPointColor(_FGHandle ControlHandle, _FGHandle GraphHandle, _u32* pColor)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->getPointColor(GraphHandle, pColor);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_setGraphVisible(_FGHandle ControlHandle, _FGHandle GraphHandle, bool Visible)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setGraphVisible(GraphHandle, Visible);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_getGraphVisible(_FGHandle ControlHandle, _FGHandle GraphHandle,
                                  bool* pVisible)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->getGraphVisible(GraphHandle, pVisible);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_addXMarker(_FGHandle ControlHandle, double Value, WCHAR* Label,
                             COLORREF Color)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->addXMarker(Value, Color, Label);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_addYMarker(_FGHandle ControlHandle, double Value, WCHAR* Label,
                             COLORREF Color)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->addYMarker(Value, Color, Label);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_removeMarker(_FGHandle ControlHandle, int MarkerId)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->removeMarker(MarkerId);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_removeGraph(_FGHandle ControlHandle, _FGHandle GraphHandle)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->removeGraph(GraphHandle);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_removeAllGraphs(_FGHandle ControlHandle)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->removeGraph(-1);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_getTitleAsUnicode(_FGHandle ControlHandle, WCHAR* pReturnBuffer,
                                    unsigned int BufferSize)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    return wcscpy_s(pReturnBuffer, BufferSize, OpenGraphs.at(ControlHandle)->getGraphControl()->getTitle().GetBuffer());
}
FG_EXPORT _s32 FG_getTitleAsAscii(_FGHandle ControlHandle, char* pReturnBuffer,
                                  unsigned int BufferSize)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    size_t CharactersConverted = 0;
    return wcstombs_s(&CharactersConverted, pReturnBuffer, BufferSize,
                      OpenGraphs.at(ControlHandle)->getGraphControl()->getTitle().GetBuffer(),
                      BufferSize - 1);
}
FG_EXPORT _s32 FG_setTitle(_FGHandle ControlHandle, WCHAR* Title)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setTitle(CString(Title));
    FG_requestRedraw(ControlHandle);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_getAxisLabelXAsUnicode(_FGHandle ControlHandle, WCHAR* pReturnBuffer,
                                         unsigned int BufferSize)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    return wcscpy_s(pReturnBuffer, BufferSize, OpenGraphs.at(ControlHandle)->getGraphControl()->getXCaption().GetBuffer());
}
FG_EXPORT _s32 FG_getAxisLabelXAsAscii(_FGHandle ControlHandle, char* pReturnBuffer,
                                       unsigned int BufferSize)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    size_t CharactersConverted = 0;
    return wcstombs_s(&CharactersConverted, pReturnBuffer, BufferSize,
                      OpenGraphs.at(ControlHandle)->getGraphControl()->getXCaption().GetBuffer(),
                      BufferSize - 1);
}
FG_EXPORT _s32 FG_setAxisLabelX(_FGHandle ControlHandle, WCHAR* Label)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setXCaption(CString(Label));
    FG_requestRedraw(ControlHandle);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_getAxisLabelYAsUnicode(_FGHandle ControlHandle, WCHAR* pReturnBuffer,
                                         unsigned int BufferSize)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    return wcscpy_s(pReturnBuffer, BufferSize, OpenGraphs.at(ControlHandle)->getGraphControl()->getYCaption().GetBuffer());
}
FG_EXPORT _s32 FG_getAxisLabelYAsAscii(_FGHandle ControlHandle, char* pReturnBuffer,
                                       unsigned int BufferSize)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    size_t CharactersConverted = 0;
    return wcstombs_s(&CharactersConverted, pReturnBuffer, BufferSize,
                      OpenGraphs.at(ControlHandle)->getGraphControl()->getYCaption().GetBuffer(),
                      BufferSize - 1);
}
FG_EXPORT _s32 FG_setAxisLabelY(_FGHandle ControlHandle, WCHAR* Label)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setYCaption(CString(Label));
    FG_requestRedraw(ControlHandle);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_enableGrid(_FGHandle ControlHandle, bool Enable)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->m_DrawGrid = Enable;
    FG_requestRedraw(ControlHandle);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_isGridEnabled(_FGHandle ControlHandle, bool* pEnabled)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return EXIT_FAILURE;
    }

    *pEnabled = OpenGraphs.at(ControlHandle)->getGraphControl()->m_DrawGrid;
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_enableMouseTracking(_FGHandle ControlHandle, bool Enable)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->setMouseTrackingEnabled(Enable);
    FG_requestRedraw(ControlHandle);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_isMouseTrackingEnabled(_FGHandle ControlHandle, bool* pEnabled)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return EXIT_FAILURE;
    }

    *pEnabled = OpenGraphs.at(ControlHandle)->getGraphControl()->getMouseTrackingEnabled();
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_setEnableGrid(_FGHandle ControlHandle, bool Enable)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    OpenGraphs.at(ControlHandle)->getGraphControl()->m_DrawGrid = Enable;
    FG_requestRedraw(ControlHandle);
    return EXIT_SUCCESS;
}
FG_EXPORT _s32 FG_getGridEnabled(_FGHandle ControlHandle, bool* pEnable)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return EXIT_FAILURE;
    }

    *pEnable = OpenGraphs.at(ControlHandle)->getGraphControl()->m_DrawGrid;
    return EXIT_SUCCESS;
}

FG_EXPORT _FGHandle FG_getMarkerHandleX(_FGHandle ControlHandle, _u32 Index)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    auto XMarkers = OpenGraphs.at(ControlHandle)->getGraphControl()->getXMarkers();
    _u32 j = 0;

    for(auto Iterator = XMarkers.begin() ; Iterator != XMarkers.end(); ++Iterator, ++j)
    {
        if(j == Index)
        {
            return Iterator->first;
        }
    }

    return -1;
}

FG_EXPORT _FGHandle FG_getMarkerHandleY(_FGHandle ControlHandle, _u32 Index)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    auto YMarkers = OpenGraphs.at(ControlHandle)->getGraphControl()->getYMarkers();
    _u32 j = 0;

    for(auto Iterator = YMarkers.begin() ; Iterator != YMarkers.end(); ++Iterator, ++j)
    {
        if(j == Index)
        {
            return Iterator->first;
        }
    }

    return -1;
}


FG_EXPORT _s32 FG_getMarkerValue(_FGHandle ControlHandle,
                                 _FGHandle Markerhandle,
                                 _f64*     pValue)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    if(!pValue)
    {
        return FG_ERROR_NULLPOINTER_PARAMETER;
    }

    auto XMarkers = OpenGraphs.at(ControlHandle)->getGraphControl()->getXMarkers();

    for(auto Iterator = XMarkers.begin() ; Iterator != XMarkers.end(); ++Iterator)
    {
        if(Markerhandle == Iterator->first)
        {
            *pValue = Iterator->second.m_Value;
            return EXIT_SUCCESS;
        }
    }

    auto YMarkers = OpenGraphs.at(ControlHandle)->getGraphControl()->getYMarkers();

    for(auto Iterator = YMarkers.begin() ; Iterator != YMarkers.end(); ++Iterator)
    {
        if(Markerhandle == Iterator->first)
        {
            *pValue = Iterator->second.m_Value;
            return EXIT_SUCCESS;
        }
    }

    return -1;
}

FG_EXPORT _s32 FG_getMarkerCaption_AsUnicode(_FGHandle ControlHandle,
                                             _FGHandle Markerhandle,
                                             wchar_t*  pBuffer,
                                             _u32      Size)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    if(!pBuffer || !Size)
    {
        return FG_ERROR_NULLPOINTER_PARAMETER;
    }

    auto XMarkers = OpenGraphs.at(ControlHandle)->getGraphControl()->getXMarkers();

    for(auto Iterator = XMarkers.begin() ; Iterator != XMarkers.end(); ++Iterator)
    {
        if(Markerhandle == Iterator->first)
        {
            return wcscpy_s(pBuffer, Size, Iterator->second.m_Caption.GetBuffer());
        }
    }

    auto YMarkers = OpenGraphs.at(ControlHandle)->getGraphControl()->getYMarkers();

    for(auto Iterator = YMarkers.begin() ; Iterator != YMarkers.end(); ++Iterator)
    {
        if(Markerhandle == Iterator->first)
        {
            return wcscpy_s(pBuffer, Size, Iterator->second.m_Caption.GetBuffer());
        }
    }

    return -1;
}


FG_EXPORT _s32 FG_getMarkerCaption_AsAscii(_FGHandle ControlHandle,
                                           _FGHandle Markerhandle,
                                           char*     pBuffer,
                                           _u32      Size)
{
    if(OpenGraphs.count(ControlHandle) == 0)
    {
        return FG_ERROR_INVALID_CONTROL_HANDLE;
    }

    if(!pBuffer || !Size)
    {
        return FG_ERROR_NULLPOINTER_PARAMETER;
    }

    auto XMarkers = OpenGraphs.at(ControlHandle)->getGraphControl()->getXMarkers();

    for(auto Iterator = XMarkers.begin() ; Iterator != XMarkers.end(); ++Iterator)
    {
        if(Markerhandle == Iterator->first)
        {
            size_t CharactersConverted = 0;
            wcstombs_s(&CharactersConverted, pBuffer, Size,
                       Iterator->second.m_Caption.GetBuffer(),
                       Size - 1);
            return CharactersConverted;
        }
    }

    auto YMarkers = OpenGraphs.at(ControlHandle)->getGraphControl()->getYMarkers();

    for(auto Iterator = YMarkers.begin() ; Iterator != YMarkers.end(); ++Iterator)
    {
        if(Markerhandle == Iterator->first)
        {
            size_t CharactersConverted = 0;
            wcstombs_s(&CharactersConverted, pBuffer, Size,
                       Iterator->second.m_Caption.GetBuffer(),
                       Size - 1);
            return CharactersConverted;
        }
    }

    return -1;
}